package com.cskaoyan.javase.oop3._0abstract._3exercise;

/**
 * 编码练习
 * 公司正在开发一套员工管理系统，需要对公司内部存在的员工进行管理
 * 公司将员工分为三类，
 *      1.普通员工负责杂项工作
 *      2.程序员负责技术开发
 *      3.经理负责统筹规划
 * 普通员工包含3个属性：姓名、工号以及工资，行为是工作
 * 程序员包含3个属性：姓名、工号以及工资，行为是工作和加班（overtime work）
 * 经理包含4个属性：姓名、工号、工资以及奖金（bonus），行为是工作
 *
 * 请使用所学的知识设计该员工系统
 * 要求类中提供必要的方法进行属性访问（description）
 *
 * 考虑到程序的扩展性和可维护性,不能用一个体系中存在的员工做父类
 * 于是我们自定义一个抽象父类
 * 来做员工继承体系的祖先类,一定要定义抽象父类吗?
 * 定义抽象父类的好处是什么呢?
 * 好处就在于有抽象方法,可以起到占位的作用
 * "作为员工,都应该工作,而且工作的内容不同"
 *
 * @since 16:16
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        AbstractStaff as;
        as = new NormalStaff("张三", 10, 10000);
        as.work();
        as.printStaff();
        as = new Programmer("李四", 13, 1000000);
        as.work();
        if (as instanceof Programmer) {
            ((Programmer) as).overTimeWork();
        }
        as.printStaff();
        as = new Manager("王二", 3, 200000, 1000000);
        as.work();
        if (as instanceof Manager) {
            System.out.println(((Manager) as).getBonus());
        }
        as.printStaff();
    }
}

abstract class AbstractStaff {
    String name;
    int staffId;
    double salary;

    public AbstractStaff(String name, int staffId, double salary) {
        this.name = name;
        this.staffId = staffId;
        this.salary = salary;
    }

    // 都要工作,所以工作的方法设置为抽象方法
    public abstract void work();

    // 打印员工信息的方法写在抽象类中,作为一个默认的实现
    public void printStaff() {
        System.out.println("姓名为" + name + "的员工,他的职工号是" + staffId + ",他的月薪资是" + salary + "💵");
    }
}

class NormalStaff extends AbstractStaff {
    public NormalStaff(String name, int staffId, double salary) {
        super(name, staffId, salary);
    }

    @Override
    public void work() {
        System.out.println("负责杂项工作!");
    }
}

class Programmer extends AbstractStaff {
    public Programmer(String name, int staffId, double salary) {
        super(name, staffId, salary);
    }

    @Override
    public void work() {
        System.out.println("负责进行技术开发工作!");
    }

    public void overTimeWork() {
        System.out.println("我每周996!");
    }
}

class Manager extends AbstractStaff {
    private double bonus;

    public Manager(String name, int staffId, double salary, double bonus) {
        super(name, staffId, salary);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    @Override
    public void work() {
        System.out.println("负责统筹规划的工作!");
    }

    // 经理类打印信息,需要增加一个额外的属性-奖金

    @Override
    public void printStaff() {
        System.out.println("姓名为" + name + "的员工,他的职工号是" + staffId + ",他的月薪资是" + salary + "💵" + ",他的奖金是" + bonus);
    }
}